package com.leha.forum.lehare.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leha.forum.lehare.entity.Permission;
import com.leha.forum.lehare.entity.User;
import com.leha.forum.lehare.entity.UserRole;
import com.leha.forum.lehare.service.PermissionService;
import com.leha.forum.lehare.service.RolePermissionService;
import com.leha.forum.lehare.service.UserRoleService;
import com.leha.forum.lehare.service.UserService;
import com.leha.forum.lehare.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @author Administrator
* @description 针对表【user】的数据库操作Service实现
* @createDate 2025-04-15 21:53:11
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService, UserDetailsService {
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RolePermissionService rolePermissionService;
    @Resource
    private PermissionService permissionService;

    /**
     * Locates the user based on the username. In the actual implementation, the search
     * may possibly be case sensitive, or case insensitive depending on how the
     * implementation instance is configured. In this case, the <code>UserDetails</code>
     * object that comes back may have a username that is of a different case than what
     * was actually requested..
     *
     * @param username the username identifying the user whose data is required.
     * @return a fully populated user record (never <code>null</code>)
     * @throws UsernameNotFoundException if the user could not be found or the user has no
     *                                   GrantedAuthority
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库中获取用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().eq(User::getUsername, username);
        User userEntity = getOne(queryWrapper);
        if (userEntity == null) {
            throw new UsernameNotFoundException(username);
        }

        // 获取用户所有权限
        List<Permission> userPermissions = this.getUserPermissions(userEntity.getUserId());

        // 将权限写入用户信息
        userEntity.authorities.addAll(userPermissions.stream().map(it -> new SimpleGrantedAuthority(it.getName())).toList());

        return userEntity;
    }

    @Override
    public List<Permission> getUserPermissions(Long userId) {
        return userRoleService.getUserRoles(userId)
                .stream()
                .map(it -> rolePermissionService.getRolePermissions(it.getRoleId(), permissionService))
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }
}




